#pragma once
#include <game/Config.h>
#include <game/ServiceProvider.h>
#include <game/ScreenBackendFactory.h>
#include <game/flow/SelectorFactory.h>
#include <game/flow/TriggerFactory.h>
#include <game/DebugInfoManager.h>
#include <game/controls/ControlFactory.h>

#include <Config.h>

#include <memory>

namespace liba {
namespace lib3d {
class Application;
namespace hard  {
class Hardware;
} // namespace hard
} // namespace lib3d
} // namespace liba

ARELLO_GAME_NAMESPACE_DECL_START
namespace flow {
class Manager;
} // namespace flow

class GameDefinition;
class ScreenManager;

class Root
	: public ServiceProvider
{
public:
	Root(liba::lib3d::Application* app);
	~Root();

	bool LifeCycle(time_float dt);
	void render(liba::lib3d::hard::Hardware* hardware);
public:
	const ScreenBackendFactory& GetBackendFactory() const { return this->backendFactory; }
	void SetBackendFactory(const ScreenBackendFactory& value) { this->backendFactory = value; }
	void SetSelectorFactory(const flow::SelectorFactory& value);
	void SetTriggerFactory(const flow::TriggerFactory& value);
	const controls::ControlFactory& GetControlFactory() { return this->controlFactory; }
	void SetControlFactory(const controls::ControlFactory& value) { this->controlFactory = value; }

	flow::Manager* GetFlowManager() { return this->flowManager.get(); }
	void SetFlowManager(std::auto_ptr<flow::Manager> value);
	void SetDebugManager(std::auto_ptr<DebugInfoManager> value) { 
		this->debugManger = value;
	}
private:
	ScreenManager* screenManager;
	liba::lib3d::Application* application;
	std::auto_ptr<flow::Manager> flowManager;

	class DelayedActionServiceImpl* delayedActionService;
	ScreenBackendFactory backendFactory;

	flow::SelectorFactory selectorFactory;
	flow::TriggerFactory triggerFactory;
	controls::ControlFactory controlFactory;

	std::auto_ptr<DebugInfoManager> debugManger;
};

ARELLO_GAME_NAMESPACE_DECL_END